/*
** Mortem's HGE Addon 1.4
** Copyright (C) 2006-2007, Osokin 'elmortem' Makar
** http://elmortem.mirgames.ru
**
** Target fader.
*/

#include <mhafader.h>

#include <math.h>
#include <mhautils.h>

HGE *mhaFader::hge = 0;

mhaFader::mhaFader(float size, mhaCallback *callback) {
	hge = hgeCreate(HGE_VERSION);

	Effect = MHAFADEREFFECT_ALPHA;
	MaxTime = Time = 0.f;
	Speed = MHAFADER_SPEED;
	Size = size;
	Callback = callback;

	DistortWidth = hge->System_GetState(HGE_SCREENWIDTH) / Size + 1;
	DistortHeight = hge->System_GetState(HGE_SCREENHEIGHT) / Size + 1;
	Distort = new hgeDistortionMesh(DistortWidth, DistortHeight);
	Target = hge->Target_Create(hge->System_GetState(HGE_SCREENWIDTH), hge->System_GetState(HGE_SCREENHEIGHT), false);
	hge->Gfx_BeginScene(Target);
	hge->Gfx_Clear(0xFFFFFFFF);
	hge->Gfx_EndScene();
}

mhaFader::~mhaFader(void) {
	hge->Target_Free(Target);
	hge->Release();
}
	
void mhaFader::Set(int effect, float time, float speed) {
	Effect = effect;
	MaxTime = Time = time;
	Speed = speed;

	hge->Gfx_BeginScene(Target);
	hge->System_Render();
	hge->Gfx_EndScene();

	Distort->Clear();
	Distort->SetBlendMode(BLEND_DEFAULT);
	Distort->SetTexture(hge->Target_GetTexture(Target));
	Distort->SetTextureRect(0, 0, hge->System_GetState(HGE_SCREENWIDTH), hge->System_GetState(HGE_SCREENHEIGHT));
	for(int i = 0; i < DistortWidth; i++) {
		for(int j = 0; j < DistortHeight; j++) {
			Distort->SetDisplacement(i, j, i * Size, j * Size, HGEDISP_TOPLEFT);
		}
	}
	if(Callback) {
		Callback->call(MHACB_FADER, MHAFADER_BEGIN);
	}
}

void mhaFader::Restore(void) {
	Time = 0.f;
}

bool mhaFader::Update(float delta) {
	if(Time <= 0.f) return true;

	int i, j;

	Time -= Speed * delta;
	if(Time < 0.f && Callback) Callback->call(MHACB_FADER, MHAFADER_END);
	if(Effect == MHAFADEREFFECT_ALPHA) {
		float a;
		for(i = 0; i < DistortWidth; i++) {
			a = (Time / MaxTime) - ((float)i / (float)(DistortWidth - 1)) * 0.3f;
			if(a < 0.f) a = 0.f;
			for(j = 0; j < DistortHeight; j++) {
				Distort->SetColor(i, j, clr(1, 1, 1, a));
			}
		}
	} else if(Effect == MHAFADEREFFECT_WAVE) {
		int ii = (float)(DistortHeight - 1) / MaxTime * Time;
		float a;
		for(j = 0; j < DistortHeight; j++) {
			if(j < ii) a = 1.f;
			else a = 0.f;
			for(i = 0; i < DistortWidth; i++) {
				Distort->SetColor(i, j, clr(1, 1, 1, a));
			}
		}
	} else if(Effect == MHAFADEREFFECT_WAVE_REVERSE) {
		int ii = (DistortHeight - 1) - (float)(DistortHeight - 1) / MaxTime * Time;
		float a;
		for(j = 0; j < DistortHeight; j++) {
			if(j > ii) a = 1.f;
			else a = 0.f;
			for(i = 0; i < DistortWidth; i++) {
				Distort->SetColor(i, j, clr(1, 1, 1, a));
			}
		}
	} else if(Effect == MHAFADEREFFECT_OCEAN) {
		float t = MaxTime - Time;
		for(i = 1; i < DistortHeight-1; i++) {
			for(j = 1; j < DistortWidth-1; j++) {
				Distort->SetDisplacement(j, i, cosf(t * 10 + (i + j) * 5.5f) * 5, sinf(t * 10 + (i + j) * 5.5f) * 5, HGEDISP_NODE);
			}
		}
		for(i = 0; i < DistortWidth; i++) {
			for(j = 0; j < DistortHeight; j++) {
				Distort->SetColor(i, j, clr(1, 1, 1, Time / MaxTime * 1.5f));
			}
		}
	} else if(Effect == MHAFADEREFFECT_WATERDOWN) {
		
	}

	return false;
}

void mhaFader::Render(void) {
	if(Time <= 0.f) return;

	Distort->Render(0, 0);
}
